let Card = require('./card.js');
let Poker = require('./poker.js');
let Utils = require('./utils.js');
let log = require('../../util/log.js');
module.exports = AI;
/**
 * 0: 不跟牌, 只出单牌.
 * 1: 跟牌, 出对子, 三带, 但不会拆顺子
 * 2: 会拆顺子,但不考虑权重.(可能把三带1给拆了)
 * 3: 拆顺子的时候,会考虑权重 ( 还未实现 )
 */
function AI(level) {
    this._level = level;
}
AI.prototype.analyze = function () {
}
// 取单牌
AI.prototype.searchDanpai = function () {
    return this._info.group[0];
}
// 取对子, 三张
AI.prototype.searchSame = function (sameN) {
    return this._info.group[sameN]
}
// 取连对, 飞机
AI.prototype.searchSeqN = function (sameN) {
    // if (sameN == 1)
    //     return this.searchSeq();
    // let info = this._info
    // let xx = this.resolve(info.group[sameN - 1], SeqSize[sameN - 1])
    // log.d("searchSeq{0}--------\n{1} ", sameN, xx.shun);
    //return xx.shun;
    return null;
}
// 取炸弹
AI.prototype.searchBomb = function () {
    return this._info.group[3]
};
// 返回王炸
AI.prototype.getWangzha = function () {
    let len = this._cards.length;
    if (len < 2)
        return null;
    let w = this._cards[len - 2];
    let W = this._cards[len - 1];
    if (w.getValue() == 13 && W.getValue() == 14) {
        return [w, W];
    }
    return null;
};
AI.prototype._follow = function (lastInfo, handCards) {
    handCards.sort(function (a, b) {
        if (a.getValue() > b.getValue()) return 1;
        else return -1;
    });
    this._cards = handCards;
    this._info = Utils.classify(handCards);
    try {
        let idList = this.getCardsByType(lastInfo);
        //log.d('跟牌:',idList);
        return toIdList(idList);
    }
    catch (e) {
        log.e(e);
        return [];
    }
}
AI.prototype._playCard = function (handCards) {
    if (handCards.length <= 0 || !handCards) {
        log.e('出现了AI单牌找不到牌的错误', handCards);
        return [];
    }

    if (this._level == 0) {
        //log.d('出单牌:', dan[0]);
        return [handCards[0].getID()];
    }
    let dan = handCards;
    let shun = null;
    let r = null;
    if (this._level > 1) {
        r = Utils.getSequence(handCards);
        //log.d('顺子:', r.seq, r.dan, r.check);
        dan = r.check.concat(r.dan);
        shun = r.seq;
    }
    let info = Utils.classify(dan);
    
    // 出顺子
    let p0 = function () {
        if (shun && shun.length > 0) {
            //log.d('出顺子:', r.seq[0])
            return toIdList(r.seq[0]);
        }
    };
    //三带
    let p1 = function () {
        if (info.group[2].length > 0) {
            let sandai = [];
            sandai.push(info.group[2][0]);
            sandai.push(info.group[2][1]);
            sandai.push(info.group[2][2]);
            if (info.group[0].length > 0) {
                sandai.push(info.group[0][0]);
            }
            else if (info.group[1].length > 1) {
                sandai.push(info.group[1][0]);
                sandai.push(info.group[1][1]);
            }
            //log.d('出三带一:', info.group[1]);
            return toIdList(sandai);
        }
    }
    //出对子
    let p2 = function () {
        if (info.group[1].length > 1) {
            let duizi = [];
            duizi.push(info.group[1][0]);
            duizi.push(info.group[1][1]);
            //log.d('出对子:', info.group[1]);
            return toIdList(duizi);
        }
    }
    //出炸弹
    let p3 = function () {
        if (info.group[3].length > 3) {
            let zhadan = [];
            zhadan.push(info.group[3][0]);
            zhadan.push(info.group[3][1]);
            zhadan.push(info.group[3][2]);
            zhadan.push(info.group[3][3]);
            //log.d('出炸弹:', info.group[3]);
            return toIdList(zhadan);
        }
        // 王炸
        return toIdList(info.group[4]);
    }
    //单牌
    let p4 = function () {
        if (info.group[0].length > 0) {
            let danpai = [];
            danpai.push(info.group[0][0]);
            //log.d('出单牌:', info.group[0]);
            return toIdList(danpai);
        }
    }
    //随机出牌，三带>出顺子>出对子>单牌
    let op = [p1, p0, p2, p4];
    let k = [];
    for (let i = 0; i < op.length; i++) {
        k[i] = {op: op[i], w: Math.random()};
    }   
    k.sort(function (a, b) {
        return a.w - b.w;
    });
    for (let i in k) {
        let result = k[i].op();
        if (result) return result;
    }
    let result = p3();
    if (result) return result;
    //实在没有出的, 就出单
    return [handCards[0].getID()];
}
AI.prototype.autoPlay = function (lastInfo, handCards) {
    //log.d('手上的牌:', handCards);
    // 如果上家没有出, 则直接出牌
    if (lastInfo != undefined) {
        if (this._level == 0)
            return []; 
        return this._follow(lastInfo, handCards);
    }   
    return this._playCard(handCards);
}
/**
 返回指定牌型
 danpai: 1,
 duizi: 2,
 sanzhang: 3,
 sandai1: 4,
 sandai2: 5,
 sidai2: 6,
 zhadan: 7,
 shunzi: 8,
 liandui: 9,
 feiji: 10,
 wangzha: 11
 */
AI.prototype.getCardsByType = function (lastInfo) {
    if (lastInfo.typeId == Card.cardType.wangzha) {
        return null;
    }
    if (lastInfo.typeId == Card.cardType.zhadan) {
        return zhadan.call(this, lastInfo) || this.getWangzha();
    }
    let len = this._cards.length;
    let wz = this.getWangzha();
    if (len == 2 && wz != null) {
        return wz;    // 只有两张, 并且是王炸时, 直接出
    }

    if (this._cards.length < lastInfo.cards.length) {
        return wz;    // 张数不够,要不起, 如果有王炸, 就出王炸
    }

    if (handler[lastInfo.typeId] != null) {
        let result = handler[lastInfo.typeId].call(this, lastInfo);
        //如果有王炸，就出王炸
        if(result==null && wz!=null){
            return wz;
        }   
        return result;
    }
    return wz;        // 如果有王炸, 就出王炸
}
function toIdList(cardList) {
    if (cardList == null) return null;
    let idlist = [];
    for (let i in cardList) {
        idlist.push(cardList[i].getID());
    }
    return idlist;
}
function sameCard(info, n, min) {
    let ls = info.group[n - 1];
    for (let i = 0; i < ls.length; i += n) {
        let card = ls[i];
        if (card.getValue() > min) {
            let ret = new Array(n);
            for (let j = 0; j < n; j++)
                ret[j] = ls[i + j];
            return ret;
        }
    }
    return null;
}
// 取n张子牌,u=1代表单张,u=2代表对子 ...
function subCard(info, n, u) {
    let ret = new Array();
    for (let k = u - 1; k < u; k++) {
        let ls = info.group[k];
        for (let i = 0; i < ls.length; i++) {
            let card = ls[i];
            ret.push(card);
            if (ret.length == n * u)
                return ret;
        }
    }
}
function zhadan(lastInfo) {
    let ls = sameCard(this._info, 4, lastInfo.base);
    if (ls != null)
        return ls;
}

function danpai(lastInfo) {
    // log.d('找单牌, 找不到单牌就拆对子', this._info);
    let seqinfo = Utils.getSequence(this._cards, 1);
    // log.d('先检测顺子,尽量不要拆', seqinfo.seq);
    // 找单牌, 找不到单牌就拆对子.
    let info = Utils.classify(seqinfo.check.concat(seqinfo.dan));
    let dz = lastInfo.dz || 0;
    let rp = Math.round(3);
    // log.d('再找单牌'); 
    for (let k = 0; k < 2; k++) {
        let ls = info.group[k];
        //log.d('k ls:',k, ls);
        for (let i in ls) {
            let card = ls[i]; 
            if (card.getValue() > lastInfo.base) {
                //log.d("返回:", lastInfo.base, card); 
                //拆对子
                if(k>0){ 

                    //上一家是地主出的牌，不需要拆对子
                    if(dz==1 && (card.getValue() - lastInfo.base)>rp   ){
                        continue;
                    }   
                    //当前是地主家的，要拆 
                    if(dz==2) {  //判断一下是不是比要出的牌大很多的情况，是的话就不拆了
                        // continue;
                    }   
                    //当前不是地主地主，拆牌，截住地主出的小于10的牌
                    if(dz==0 && lastInfo.base<9 ) {
                        continue;
                    }   

                }   
                return [card];
            }   
        }   
    }   
    for (let k = 0; k < seqinfo.seq.length; k++) {
        let ls = seqinfo.seq[k];
        if (ls.length > 5 && ls[ls.length - 1].getValue() > lastInfo.base) {
            return [ls[ls.length - 1]];
        }
    }   
    //如果我和上家都是农民, 则不出王.
    //log.d("pass");
}
function duizi(lastHands) {
    let seqinfo = Utils.getSequence(this._cards, 1);
    //选连子以外的对子
    let info = Utils.classify(seqinfo.check.concat(seqinfo.dan));
    return sameCard(info, 2, lastHands.base);
}
function sanzhang(lastHands) {
    return sameCard(this._info, 3, lastHands.base);
}
function sandai1(lastHands) {
    let c3 = sameCard(this._info, 3, lastHands.base);
    if (c3 == null) return;
    let plus = null;
    if (lastHands.cards.length == 4)
        plus = subCard(this._info, 1, 1);    // 3+1
    else
        plus = subCard(this._info, 1, 2);    // 3+1对
    if (plus == null)
        return null;
    else
        return c3.concat(plus)
}
function sidai2(lastHands) {
    let c4 = sameCard(this._info, 4, lastHands.base);
    if (c4 == null) return;
    let plus = null;
    if (lastHands.cards.length == 6)
        plus = subCard(this._info, 2, 1);    // 4+2单
    else
        plus = subCard(this._info, 2, 2);    // 4+2对
    if (plus == null)
        return null;
    else
        return c4.concat(plus)
}
function shunzi(lastHands) {
    let r = Utils.getSequence(this._info.group[0], 1);
    let ret = null;
    for (let i in r.seq) {
        let ls = r.seq[i]
        if (ls.length >= lastHands.length && ls[0].getValue() > lastHands.base) {
            if (ret == null || ret.length > ls.length) {
                ret = ls;
            }
        }
    }
    //返回ret
    if (ret == null || ret.length == lastHands.length) return ret;
    //只取一段
    return ret.slice(0, lastHands.length);
}
function liandui(lastHands) {
    let r = Utils.getSequence(this._info.group[1], 2);
    let ret = null;
    for (let i in r.seq) {
        let ls = r.seq[i];
        if (ls.length >= lastHands.length && ls[0].getValue() > lastHands.base) {
            if (ret == null || ret.length > ls.length) {
                ret = ls;
            }
        }
    }
    //返回ret
    if (ret == null || ret.length == lastInfo.length) return ret;
    //只取一段
    return ret.slice(0, lastInfo.length);
}
function feiji(lastInfo) {
    let last = Utils.classify(lastInfo.cards);
    let fj = last.group[2];
    let fjLen = fj.length;
    let myfj = this._info.group[2];
    if (myfj.length < fj.length) return null;
    // let rs = Utils.getSHunzi(this._info.group[2],3);
    // let ret = null;
    // for (let i in rs) {
    //     if (rs[i].length >= fjLen && rs[i][0].getValue() > lastInfo.cards[0].getValue()) {
    //         if (ret == null || ret.length > rs[i].length) {
    //             ret = rs[i];
    //         }
    //     }
    // }
    // //返回ret
    // if (ret == null || ret.length == fjLen) return ret;
    // //只取一段
    // return ret.slice(0,fjLen);
    //
    return null;
}
handler = [null, danpai, duizi, sanzhang, sandai1, sandai1, sidai2, zhadan, shunzi, liandui, feiji]